ffmpeg 读取RTSP流 av

您所在的位置:网站首页 read函数 阻塞 ffmpeg 读取RTSP流 av

ffmpeg 读取RTSP流 av

2023-03-14 05:43| 来源: 网络整理| 查看: 265

ffmpeg拉取RTSP流 正常操作不会有问题 但是如果途中,

把RTSP的流断了, 发现 会卡死 在avformat_find_stream_info函数中,

把这个函数注释掉的话就会卡死在av_read_frame中 ,大概需要30m才会返回

网上搜了下 无论是 设置超时方法 还是 回调函数都不管用,不知道为什么。

经过测试实际的断流有两种情况:

1.是RTSP服务断了 ,这种情况 open_input 那里会返回失败,比较好处理

2.是RTSP服务没断,但是没有视频流了 这种情况会导致open_input成功,但是会导致程序一直卡死在av_read_frame函数里面 具体网上可以搜 FFMpeg源码里面就这么写了,

大体上有两种方法 设置超时处理 第一种是 通过av_dict_set函数设置timeout超时时间,但是我这么试了没有效果,所以只能是第二种方法,设置callback 经过测试 这种callback机制可以实现

具体原因下面FFmpeg代码这么写的

static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf, int size, int size_min, int (*transfer_func)(URLContext *h, uint8_t *buf, int size)) { int ret, len; int fast_retries = 5; int64_t wait_since = 0; len = 0; while (len < size_min) { if (ff_check_interrupt(&h->interrupt_callback)) return AVERROR_EXIT; ret = transfer_func(h, buf + len, size - len); if (ret == AVERROR(EINTR)) continue; if (h->flags & AVIO_FLAG_NONBLOCK) return ret; if (ret == AVERROR(EAGAIN)) { ret = 0; if (fast_retries) { fast_retries--; } else { if (h->rw_timeout) { if (!wait_since) wait_since = av_gettime_relative(); else if (av_gettime_relative() > wait_since + h->rw_timeout) return AVERROR(EIO); } av_usleep(1000); } } else if (ret == AVERROR_EOF) return (len > 0) ? len : AVERROR_EOF; else if (ret < 0) return ret; if (ret) { fast_retries = FFMAX(fast_retries, 2); wait_since = 0; } len += ret; } return len; }

可以看到这个while循环里面有一个判断有没有callback 如果没有callback 就会一直卡在这个循环里直到读到了数据,经过实际测试,如果没有callback 视频流断了 之后又重新打开的话,大概需要30-50S左右 av_read_frame会返回失败。可以看下ff_check_interrupt函数

int ff_check_interrupt(AVIOInterruptCB *cb) { if (cb && cb->callback) return cb->callback(cb->opaque); return 0; }

直接返回callback的,只要是非0 就会跳出这个循环。

可以通过av_time 获取时间,然后在callback里面判断超时时间 比如3s 超过3s之后 callback返回非0 就可以

版权声明:本文为CSDN博主「QMCY_jason」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:ffmpeg 读取RTSP流 av_read_frame 阻塞 卡死 的问题



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3